﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;
using System.Collections.Generic;

namespace SLASCIICore
{
    public class ASCIIRenderer
    {
        private Dictionary<int, Dictionary<int, byte>> characters = new Dictionary<int,Dictionary<int,byte>>();
        private Dictionary<int, Dictionary<int, CellColor>> foregroundColors = new Dictionary<int,Dictionary<int,CellColor>>();
        private Dictionary<int, Dictionary<int, CellColor>> backgroundColors = new Dictionary<int,Dictionary<int,CellColor>>();
        private ImageBrushes brushes = new ImageBrushes();
        private GridBoard board;
        public GridBoard Board
        {
            get
            {
                return board;
            }
            set
            {
                board = value;
            }
        }
        public ASCIIRenderer()
        {
            foreach (CellColor theColor in new CellColor[]{CellColor.Black,CellColor.Blue,CellColor.Green,CellColor.Cyan,CellColor.Red,CellColor.Magenta,CellColor.Yellow,CellColor.LightGray,CellColor.DarkGray,CellColor.LightBlue,CellColor.LightGreen,CellColor.LightCyan,CellColor.LightRed,CellColor.LightMagenta,CellColor.LightYellow,CellColor.White})
            {
                for (int theCharacter = byte.MinValue; theCharacter <= byte.MaxValue; ++theCharacter)
                {
                    brushes.LookUpTable.Add(string.Format("{0}_{1}", theCharacter, (int)theColor), string.Format("images/{0}_{1}.png", theCharacter, (int)theColor));
                }
            }
        }
        public byte GetCellCharacter(int column, int row)
        {
            if (characters.ContainsKey(column) && characters[column].ContainsKey(row))
            {
                return characters[column][row];
            }
            else
            {
                return byte.MinValue;
            }
        }
        public CellColor GetCellForegroundColor(int column, int row)
        {
            if (foregroundColors.ContainsKey(column) && foregroundColors[column].ContainsKey(row))
            {
                return foregroundColors[column][row];
            }
            else
            {
                return byte.MinValue;
            }
        }
        public CellColor GetCellBackgroundColor(int column, int row)
        {
            if (backgroundColors.ContainsKey(column) && backgroundColors[column].ContainsKey(row))
            {
                return backgroundColors[column][row];
            }
            else
            {
                return byte.MinValue;
            }
        }
        public void SetCellCharacter(int column, int row, byte theCharacter)
        {
            if (!characters.ContainsKey(column))
            {
                characters.Add(column, new Dictionary<int, byte>());
            }
            if (characters[column].ContainsKey(row))
            {
                characters[column][row] = theCharacter;
            }
            else
            {
                characters[column].Add(row, theCharacter);
            }
        }
        public void SetCellForegroundColor(int column, int row, CellColor theColor)
        {
            if (!foregroundColors.ContainsKey(column))
            {
                foregroundColors.Add(column, new Dictionary<int, CellColor>());
            }
            if (foregroundColors[column].ContainsKey(row))
            {
                foregroundColors[column][row] = theColor;
            }
            else
            {
                foregroundColors[column].Add(row, theColor);
            }
        }
        public void SetCellBackgroundColor(int column, int row, CellColor theColor)
        {
            if (!backgroundColors.ContainsKey(column))
            {
                backgroundColors.Add(column, new Dictionary<int, CellColor>());
            }
            if (backgroundColors[column].ContainsKey(row))
            {
                backgroundColors[column][row] = theColor;
            }
            else
            {
                backgroundColors[column].Add(row, theColor);
            }
        }
        public void SetCells(int left, int top, int width, int height, byte theCharacter, bool setCharacter, CellColor theForegroundColor, bool setForeground, CellColor theBackgroundColor, bool setBackground)
        {
            for (int column = left; column < left + width; ++column)
            {
                if (column >= 0 && column < Board.Columns)
                {
                    for (int row = top; row < top + height; ++row)
                    {
                        if (row >= 0 && row < Board.Rows)
                        {
                            if (setCharacter)
                            {
                                SetCellCharacter(column, row, theCharacter);
                            }
                            if (setForeground)
                            {
                                SetCellForegroundColor(column, row, theForegroundColor);
                            }
                            if (setBackground)
                            {
                                SetCellBackgroundColor(column, row, theBackgroundColor);
                            }
                        }
                    }
                }
            }
        }
        public void SetCells(int left, int top, int width, int height, byte theCharacter)
        {
            SetCells(left, top, width, height, theCharacter, true, CellColor.Black, false, CellColor.Black, false);
        }
        public void SetCells(int left, int top, int width, int height, byte theCharacter, CellColor theForegroundColor)
        {
            SetCells(left, top, width, height, theCharacter, true, theForegroundColor, true, CellColor.Black, false);
        }
        public void SetCells(int left, int top, int width, int height, byte theCharacter, CellColor theForegroundColor, CellColor theBackgroundColor)
        {
            SetCells(left, top, width, height, theCharacter, true, theForegroundColor, true, theBackgroundColor, true);
        }

        public void SetCell(int column, int row, byte theCharacter, bool setCharacter, CellColor theForegroundColor, bool setForeground, CellColor theBackgroundColor, bool setBackground)
        {
            SetCells(column, row, 1, 1, theCharacter, setCharacter, theForegroundColor, setForeground, theBackgroundColor, setBackground);
        }
        public void SetCell(int column, int row, byte theCharacter)
        {
            SetCell(column, row, theCharacter, true, CellColor.Black, false, CellColor.Black, false);
        }
        public void SetCell(int column, int row, byte theCharacter, CellColor theForegroundColor)
        {
            SetCell(column, row, theCharacter, true, theForegroundColor, true, CellColor.Black, false);
        }
        public void SetCell(int column, int row, byte theCharacter, CellColor theForegroundColor, CellColor theBackgroundColor)
        {
            SetCell(column, row, theCharacter, true, theForegroundColor, true, theBackgroundColor, true);
        }

        public void WriteText(int left, int top, string theString, CellColor theForegroundColor, CellColor theBackgroundColor)
        {
            if (top >= 0 && top < Board.Rows)
            {
                foreach (char character in theString)
                {
                    if (left >= 0 && left < Board.Columns)
                    {
                        SetCell(left,top,(byte)character,  theForegroundColor,  theBackgroundColor);
                    }
                    left++;
                }
            }
        }

        public void Render(int left, int top, int width, int height)
        {
            int right = left + width;
            int bottom = top + height;
            if (left < 0) left = 0;
            if (top < 0) top = 0;
            if (right > board.Columns) right = board.Columns;
            if (bottom > board.Rows) bottom = board.Rows;
            for (int column = left; column < right; ++column)
            {
                for (int row = top; row < bottom; ++row)
                {
                    ImageBrush backBrush = brushes[string.Format("219_{0}", (int)GetCellBackgroundColor(column, row))];
                    ImageBrush foreBrush = brushes[string.Format("{0}_{1}", GetCellCharacter(column, row), (int)GetCellForegroundColor(column, row))];
                    if (Board[column][row][0].Fill != backBrush)
                    {
                        Board[column][row][0].Fill = backBrush;
                    }
                    else
                    {
                    }
                    if (Board[column][row][1].Fill != foreBrush)
                    {
                        Board[column][row][1].Fill = foreBrush;
                    }
                    else
                    {
                    }
                }
            }
        }
        public void Render()
        {
            Render(0, 0, Board.Columns, Board.Rows);
        }

    }
}
